package com.plum.admin.modules.sys.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.plum.admin.common.exception.BaseException;
import com.plum.admin.common.util.DeptUtil;
import com.plum.admin.modules.sys.entity.SysDept;
import com.plum.admin.modules.sys.entity.SysUser;
import com.plum.admin.modules.sys.mapper.SysDeptMapper;
import com.plum.admin.modules.sys.service.ISysDeptService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.plum.admin.modules.sys.service.ISysUserService;
import com.plum.admin.modules.sys.vo.DeptTreeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 部门管理 服务实现类
 * </p>
 *
 * @author 子丶沫
 * @since 2021-08-13
 */
@Service
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements ISysDeptService {

    @Autowired
    private ISysUserService userService;
    @Override
    public List<String> queryDeptIds(String deptId) {
        SysDept sysDept = this.findDept(deptId);
        List<String> deptIdList = new ArrayList<>();
        if(ObjectUtil.isNotNull(sysDept)){
            deptIdList.add(sysDept.getId());
            addDeptIdList(deptIdList,sysDept);
        }
        return deptIdList;
    }

    @Override
    public List<DeptTreeVo> getDeptTreeData() {
        List<SysDept> deptList = baseMapper.selectList(Wrappers.emptyWrapper());
        List<DeptTreeVo> treeVoList = deptList.stream()
                .filter(dept -> StrUtil.isNotBlank(dept.getParentId()) && dept.getParentId().equals("0"))
                .map(data -> {
                    DeptTreeVo deptTreeVo = new DeptTreeVo();
                    deptTreeVo.setKey(data.getId());
                    deptTreeVo.setLabel(data.getName());
                    deptTreeVo.setParentId(data.getParentId());
                    deptTreeVo.setDeptId(data.getId());
                    deptTreeVo.setStatus(data.getStatus());
                    deptTreeVo.setSort(data.getSort());
                    deptTreeVo.setRemark(data.getRemark());
                    return deptTreeVo;
                }).collect(Collectors.toList());
        DeptUtil.findChildren(treeVoList,deptList);
        setLeaf(treeVoList);
        return treeVoList;
    }

    @Override
    public boolean deleteDept(List<String> idList) {
        List<String> deptIdList=Lists.newArrayList();
        for(String deptId:idList){
            deptIdList.add(deptId);
            checkChildrenDept(deptIdList,deptId);
        }
        List<SysUser> userIdList = userService.list(Wrappers.<SysUser>query()
                .lambda()
                .select(SysUser::getId)
                .in(SysUser::getDeptId, deptIdList));
        if(CollUtil.isNotEmpty(userIdList)){
            throw new BaseException("部门下存在用户,无法删除");
        }
        return baseMapper.deleteBatchIds(idList)>0;
    }

    private void setLeaf(List<DeptTreeVo> list){
        for (DeptTreeVo treeVo : list) {
            List<DeptTreeVo> children=treeVo.getChildren();
            if(CollUtil.isNotEmpty(children)){
                treeVo.setLeaf(false);
            }else{
                treeVo.setLeaf(true);
            }
            setLeaf(children);
        }
    }
    private void addDeptIdList(List<String> deptIdList, SysDept dept) {
        List<SysDept> children = dept.getChildren();
        if(CollectionUtil.isNotEmpty(children)){
            for(SysDept sysDept:children){
                deptIdList.add(sysDept.getId());
                addDeptIdList(deptIdList,sysDept);
            }
        }
    }
    private void checkChildrenDept(List<String> deptIdList,String deptId){
        List<SysDept> deptList = baseMapper.selectList(Wrappers.<SysDept>query().lambda().select(SysDept::getId, SysDept::getParentId).eq(SysDept::getParentId, deptId));
        if(CollUtil.isNotEmpty(deptIdList)){
            for(SysDept dept:deptList){
                deptIdList.add(dept.getId());
                checkChildrenDept(deptIdList,dept.getId());
            }
        }
    }
    private SysDept findDept(String deptId){
        List<SysDept> departments = baseMapper.selectList(Wrappers.<SysDept>query().select("id", "name", "parent_id", "sort", "create_time"));
        Map<String, SysDept> deptMap = departments
                .stream()
                .collect(Collectors.toMap(SysDept::getId, dept -> dept));
        for(SysDept dept:deptMap.values()){
            SysDept parent = deptMap.get(dept.getParentId());
            if(ObjectUtil.isNotNull(parent)){
                List<SysDept> children = parent.getChildren() == null ? Lists.newArrayList() : parent.getChildren();
                children.add(dept);
                parent.setChildren(children);
            }
        }
        return deptMap.get(deptId);
    }
}
